#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<functional>

using namespace std;

#define TNUM 4
typedef void (*func_t)(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond);
volatile bool quit=true;

class ThreadData
{
public:
    ThreadData(const string& name,func_t func,pthread_mutex_t* mutex,pthread_cond_t* cond)
    :_name(name)
    ,_func(func)
    ,_mutex(mutex)
    ,_cond(cond)
    {

    }
public:
    string _name;
    func_t _func;
    pthread_mutex_t* _mutex;
    pthread_cond_t* _cond;
};
void func1(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        cout<<"thread -- 下载"<<endl;
        pthread_mutex_unlock(mutex);
    }
}
void func2(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        if(quit)
        {
            cout<<"thread -- 打印"<<endl;
        }
        pthread_mutex_unlock(mutex);
    }
}
void func3(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        cout<<"thread -- 读取用户信息"<<endl;
        pthread_mutex_unlock(mutex);
    }
}
void func4(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        cout<<"thread -- 刷新用户信息"<<endl;
        pthread_mutex_unlock(mutex);
    }
}
void* Entry(void* args)
{
    ThreadData* td=(ThreadData*)args;
    td->_func(td->_name,td->_mutex,td->_cond);
    delete td;
    return nullptr;
}
int main()
{
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    pthread_mutex_init(&mutex,nullptr);
    pthread_cond_init(&cond,nullptr);

    pthread_t tid[TNUM];
    func_t funcs[TNUM]={func1,func2,func3,func4};
    for(int i=0;i<TNUM;i++)
    {
        string name="thread";
        name+=to_string(i+1);
        ThreadData* td=new ThreadData(name,funcs[i],&mutex,&cond);
        pthread_create(tid+i,nullptr,Entry,(void*)td);
    }
    sleep(1);
    int cnt=10;
    while(cnt)
    {
        sleep(1);
        pthread_cond_signal(&cond);
        cout<<"thread signal "<<cnt--<<endl;
    }
    quit=true;
    pthread_cond_broadcast(&cond);
    for(int i=0;i<TNUM;i++)
    {
        pthread_join(tid[i],nullptr);
    }
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}
// #define TNUM 4

// volatile bool quit=true;
// typedef void (*func_t)(const string& name,pthread_mutex_t& mutex,pthread_cond_t& cond);

// class ThreadData
// {
// public: 
//     ThreadData(const string& name,func_t func,pthread_mutex_t& mutex,pthread_cond_t& cond)
//     :_name(name)
//     ,_func(func)
//     ,_mutex(mutex)
//     ,_cond(cond)
//     {

//     }
// public:
//     string _name;
//     func_t _func;
//     pthread_mutex_t _mutex;
//     pthread_cond_t _cond;
// };

// void func1(const string& name,pthread_mutex_t& mutex,pthread_cond_t& cond)
// {
//     while(quit)
//     {
//         pthread_mutex_lock(&mutex);
//         pthread_cond_wait(&cond,&mutex);
//         cout<<"thread -- 下载"<<endl;
//         pthread_mutex_unlock(&mutex);
//     }
// }
// void func2(const string& name,pthread_mutex_t& mutex,pthread_cond_t& cond)
// {
//     while(quit)
//     {
//         pthread_mutex_lock(&mutex);
//         pthread_cond_wait(&cond,&mutex);
//         if(quit)
//         {
//             cout<<"thread -- 打印"<<endl;
//         }
//         pthread_mutex_unlock(&mutex);
//     }
// }
// void func3(const string& name,pthread_mutex_t& mutex,pthread_cond_t& cond)
// {
//     while(quit)
//     {
//         pthread_mutex_lock(&mutex);
//         pthread_cond_wait(&cond,&mutex);
//         cout<<"thread -- 读取用户的数据"<<endl;
//         pthread_mutex_unlock(&mutex);
//     }
// }
// void func4(const string& name,pthread_mutex_t& mutex,pthread_cond_t& cond)
// {
//    while(quit)
//    {
//         pthread_mutex_lock(&mutex);
//         pthread_cond_wait(&cond,&mutex);
//         cout<<"thread -- 刷新用户数据"<<endl;
//         pthread_mutex_unlock(&mutex);
//    } 
// }
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }
// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_cond_t cond;
//     pthread_mutex_init(&mutex,nullptr);
//     pthread_cond_init(&cond,nullptr);

//     pthread_t tid[TNUM];
//     func_t funcs[TNUM]={func1,func2,func3,func4};
//     for(int i=0;i<TNUM;i++)
//     {
//         string name="thread";
//         name+=to_string(i+1);
//         ThreadData* td=new ThreadData(name,funcs[i],mutex,cond);
//         pthread_create(tid+i,nullptr,Entry,(void*)td);
//     }
//     sleep(2);
//     int cnt=10;
//     while(cnt)
//     {
//         sleep(1);
//         pthread_cond_signal(&cond);
//         cout<<"thread signal:"<<cnt--<<endl;
//     }
//     quit=false;
//     pthread_cond_broadcast(&cond);
//     for(int i=0;i<TNUM;i++)
//     {
//         pthread_join(tid[i],nullptr);
//     }
//     pthread_mutex_destroy(&mutex);
//     pthread_cond_destroy(&cond);
//     return 0;
// }
//#define TNUM 3
//强迫他去内存当中读取数据
// volatile bool quit=false;
// typedef void (*func_t)(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond);

// class ThreadData
// {
// public: 
//     ThreadData(string name,func_t func,pthread_mutex_t* mutex,pthread_cond_t* cond)
//     :_name(name)
//     ,_mutex(mutex)
//     ,_cond(cond)
//     ,_func(func)
//     {
        
//     }
// public:
//     string _name;
//     func_t _func;
//     pthread_cond_t* _cond;
//     pthread_mutex_t* _mutex;
// };
// void func1(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"thread -- 下载"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func2(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         if(!quit)
//         {
//             cout<<"thread -- 打印"<<endl;
//         }
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func3(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"thread -- 读取用户数据"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }
// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_cond_t cond;
//     pthread_mutex_init(&mutex,nullptr);
//     pthread_cond_init(&cond,nullptr);

//     pthread_t tid[TNUM];
//     func_t funcs[TNUM]={func1,func2,func3};
//     for(int i=0;i<TNUM;i++)
//     {
//         string name="thread";
//         name+=to_string(i+1);
//         ThreadData* td=new ThreadData(name,funcs[i],&mutex,&cond);
//         pthread_create(tid+i,nullptr,Entry,(void*)td);
//     }
//     sleep(2);
//     int cnt=10;
//     while(cnt)
//     {
//         sleep(1);
//         pthread_cond_signal(&cond);
//         cout<<"thread signal:"<<cnt--<<endl;
//     }
//     cout<<"ctrl done"<<endl;
//     quit=true;
//     pthread_cond_broadcast(&cond);
//     for(int i=0;i<TNUM;i++)
//     {
//         pthread_join(tid[i],nullptr);
//     }
//     pthread_mutex_destroy(&mutex);
//     pthread_cond_destroy(&cond);
//     return 0;
// }